package com.tomica.mailsigner.fragment;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import iaik.pkcs.pkcs11.objects.ac;

import cfca.mobile.keydevice.AudioToken;

import com.Wsdl2Code.WebServices.SignService.VectorByte;
import com.Wsdl2Code.WebServices.SignService.VectorString;
import com.entersafe.safeca.Constant;
import com.entersafe.safeca.MyProgressDialog;
import com.entersafe.safeca.P11Other;
import com.tomica.mailsigner.R;
import com.tomica.mailsigner.common.SettingsModel;
import com.tomica.mailsigner.signpdf.SignPDFModel;
import com.tomica.mailsigner.token.Token;

import android.app.Activity;
import android.app.AlertDialog.Builder;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class SignPdfFragment extends Fragment implements OnClickListener{

	public interface SignPdfListener{
		public Uri getPdfUri();
	}

	private static final String TAG = "SignPDFFragment";
	private static final int PICKFILE_RESULT_CODE = 1;
	private static final int REQUEST_CODE = 0;
	private TextView txtFileName;
	private Button btnChooseFile;
	private Button btnSignFile;
	private LinearLayout layout;
	private Uri uri;
	
	
	public SignPDFModel mModel;
	public  Context context;
	public  Handler handler;
	public Resources res;
	
	private Token token;
	private BroadcastReceiver headSetReceiver = null;
	
	private String randomString;
	public MyProgressDialog progressDialog;
	private String pin;
	private String fileName;
	String signedFile;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		
		context = getActivity();
		res = getResources();
		SignPdfListener activity = (SignPdfListener) getActivity();
		uri = activity.getPdfUri();
		
		progressDialog = new MyProgressDialog(context);
		
		handler = new Handler(){
			public void handleMessage(Message msg) {
				switch(msg.what) {
				case Constant.GET_SIGNED_PDF_OK:
					// Complete sign data. Showing for user:
					progressDialog.dismiss();
					CharSequence text = context.getString(R.string.msg_sign_pdf_successful);
					Toast toast = Toast.makeText(context, text, Toast.LENGTH_SHORT);
					toast.show();
					
					// TODO : What to do next with that signed file???
					// May save to storage or forward to send a email.
					VectorByte vectorData= (VectorByte) msg.obj;
					byte[] fileData = vectorData.toBytes();
					
					// Save data to SD card first.
					new SaveFileTask().execute(fileData);
					callIntentSendMail();
					
					break;
				case Constant.GET_PASSWORD:
					progressDialog.setShowInfo(getResources().getString(R.string.inform_sign_onprogress));
					progressDialog.show();
					mModel.signPdf(getPdfBase64(uri), pin);
					break;
				case Constant.WRONG_PASSWORD:
					// Wrong password, user have to re-enter.
					showDialog();
					break;
				case Constant.PDF_SIGNED_PKCS_OK:
					String signedData = (String) msg.obj;
					mModel.getSignedPdfFile(randomString, signedData);
					
					break;	
				case Constant.UP_PDF_OK:
					// Call to sign PKCS11
					// Get data from server response:
					//result !=null sẽ có 2 phần tử 
                    //result[0]: chứa chuỗi random định danh cho giao dịch
                    //result[1]: dữ liệu Server trả về dạng base64,  client cần ký lên dữ liệu này
					VectorString vectorResult = (VectorString) msg.obj;
					randomString = (String) vectorResult.getProperty(0);
					String serverDataBase64 = (String) vectorResult.getProperty(1);
					
					mModel.signObjectString(serverDataBase64, pin);
					
		        	Log.d(TAG, "Upload PDF OK");
					break;
				case Constant.SERVICE_EXCEPTION:
//					
//					// XXX Save data to SD card first.
//					new SaveFileTask().execute(getPdfBase64());
//					callIntentSendMail();
//					
					progressDialog.dismiss();
					String message = getResources().getString(R.string.inform_error_internal_server);
					showMessage(message);
					break;
				case Constant.UP_PDF_FAIL:
					progressDialog.dismiss();
					break;
				case Constant.GET_SIGNED_PDF_FAIL:
					progressDialog.dismiss();
					
					break;
				case Constant.PDF_SIGNED_PKCS_FAIL:
					progressDialog.dismiss();
					break;
				case Constant.SHOWPROGRESSDIALOG:
					Log.e(Constant.Debug, "Dialog of connecting token");
					progressDialog.setShowInfo(res.getString(R.string.inform_tryconnect_init));
					progressDialog.show();
					super.handleMessage(msg);
					break;
				case Constant.CLOSEPROGRESSDIALOG:
					progressDialog.dismiss();
					super.handleMessage(msg);
					break;
				case Constant.SHOWERRINFO:
					if (null != msg.obj) {
						if (msg.obj.toString().compareTo(
								res.getString(R.string.inform_handset_connectfail)) == 0) {
							String title, button;
							button = res.getString(R.string.inform_button_OK);
							title = res.getString(R.string.inform_title);
							new Builder(context)
									.setTitle(title)
									.setMessage(msg.obj.toString())
									.setPositiveButton(button,
											new DialogInterface.OnClickListener() {

												@Override
												public void onClick(
														DialogInterface arg0,
														int arg1) {
//													finish();
												}
											}).show();
						} else
							showMessage(msg.obj.toString());
					}
					super.handleMessage(msg);
					break;
				case Constant.TOKEN_CONNECT_OK:
					// Show Toast inform that token connect successfully.
					CharSequence textOK = context.getString(R.string.inform_token_connect_ok);
					Toast toastOk = Toast.makeText(context, textOK, Toast.LENGTH_SHORT);
					toastOk.show();
					break;
				default:
					super.handleMessage(msg);
				}
			}
		};
		
		mModel = new SignPDFModel(context, handler);
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// Inflate the layout for this fragment
		View rootView = inflater.inflate(R.layout.fragment_sign_pdf, container, false);

		txtFileName = (TextView) rootView.findViewById(R.id.txtPdfFileName);
		btnChooseFile = (Button) rootView.findViewById(R.id.btnChoosePdfFile);
		btnChooseFile.setOnClickListener(this);
		btnSignFile = (Button) rootView.findViewById(R.id.btnSignPdfFile);
		btnSignFile.setOnClickListener(this);
		layout = (LinearLayout) rootView.findViewById(R.id.layoutPdfFile);
		layout.setOnClickListener(this);

		return rootView;
	}

	@Override
	public void onPause(){
		super.onPause();

	}

	@Override
	public void onClick(View v) {
		switch (v.getId()){
		case R.id.layoutPdfFile:
			
			break;
		case R.id.btnChoosePdfFile:
			try{
				Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
				intent.setType("file/*");
				startActivityForResult(intent,PICKFILE_RESULT_CODE);
			}
			catch(ActivityNotFoundException exp){
				Toast.makeText(getActivity().getBaseContext(), getActivity().getString(R.string.msg_no_file_picker),Toast.LENGTH_LONG).show();
			}

			break;
		case R.id.btnSignPdfFile:
			showDialog();
			break;
		default:
			break;
		}

	}

	public void updatePdfFile(Uri uri){
		if (uri != null){
			String fileName = uri.getLastPathSegment();
			txtFileName.setText(fileName);
			setSignEnable(true);
		} else {
			setSignEnable(false);
		}
	}

	public void setSignEnable(boolean enable){
		if (enable){
			btnSignFile.setEnabled(true);
			layout.setEnabled(true);
		} else {
			btnSignFile.setEnabled(false);
			layout.setEnabled(false);
		}
	}

	@Override
	public void onResume() {
		super.onResume();
		Log.v(TAG, "On resume Sign PDF");
		updatePdfFile(uri);
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch(requestCode){
		case PICKFILE_RESULT_CODE:
			if(resultCode==Activity.RESULT_OK){

				String FilePath = data.getData().getPath();
				String FileName = data.getData().getLastPathSegment();
				int lastPos = FilePath.length() - FileName.length();
				String Folder = FilePath.substring(0, lastPos);
				uri = Uri.fromFile(new File(FilePath));
				
				Log.v(TAG, "File: "+FilePath);
				Log.v(TAG, "Uri: "+uri.toString());
			}
			break;
		case REQUEST_CODE:

			if (resultCode == Activity.RESULT_OK) {
				pin = data.getStringExtra("pass");
				Log.v(TAG, pin);
				progressDialog.setShowInfo(getResources().getString(R.string.inform_sign_onprogress));
				progressDialog.show();
				mModel.signPdf(getPdfBase64(uri), pin);

				// Show progressbar
			} else if (resultCode == Activity.RESULT_CANCELED){
				// After Cancel code.
			}
			break;
		}
	}
	
	public byte[] getPdfBase64(Uri uri){
		fileName = uri.getLastPathSegment();
		Log.v(TAG,"Uri-"+uri.toString()+" name ="+fileName);
		ContentResolver resolver = context.getContentResolver();
		try {
			InputStream input = resolver.openInputStream(uri);
			return mModel.getBytes(input);
			//return IOUtils.toByteArray(input);
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public boolean isOnline() {
	    ConnectivityManager cm =
	        (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
	    NetworkInfo netInfo = cm.getActiveNetworkInfo();
	    if (netInfo != null && netInfo.isConnectedOrConnecting()) {
	        return true;
	    }
	    return false;
	}
	
	private void showMessage(String msg) {
		if (null == msg || "" == msg)
			return;

		String title, button;
		button = getResources().getString(R.string.inform_button_OK);
		title = getResources().getString(R.string.inform_title);
		new Builder(context).setTitle(title).setMessage(msg)
				.setPositiveButton(button, null).show();
	}
	
	class SaveFileTask extends AsyncTask<byte[], String, String> {
		@Override
		protected String doInBackground(byte[]... jpeg) {
			String array[] = fileName.split("\\.(?=[^\\.]+$)"); 
			signedFile = array[0]+getResources().getString(R.string.txt_signed_file)+"."+array[1];
			Log.v(TAG, "Save file: "+ signedFile);
			File pdfFile=
					new File(Environment.getExternalStorageDirectory(),
							signedFile);

			if (pdfFile.exists()) {
				pdfFile.delete();
			}

			try {
				FileOutputStream fos=new FileOutputStream(pdfFile.getPath());

				fos.write(jpeg[0]);
				fos.close();
			}
			catch (java.io.IOException e) {
				Log.e(TAG, "Exception in saving file", e);
			}

			return(null);
		}

		protected void onPostExecute(Long result) {
			
		}
	}
	
	public void callIntentSendMail() {
		try {
			File pdfFile = new File(Environment.getExternalStorageDirectory(),
					signedFile);

			if (!pdfFile.exists()) {
				// File not exist, error with memory
				Log.v(TAG, "Read pdf file error");
				return;
			}
			Log.i(getClass().getSimpleName(), "send  task - start");
			final Intent emailIntent = new Intent(
					android.content.Intent.ACTION_SEND);
			emailIntent.setType("plain/text");
			Uri uri = Uri.fromFile(pdfFile);
			emailIntent.putExtra(Intent.EXTRA_STREAM,uri);
			this.startActivity(Intent
					.createChooser(emailIntent, getResources().getString(R.string.msg_choose_mail)));

		} catch (Throwable t) {
			Toast.makeText(context, "Request failed: " + t.toString(),
					Toast.LENGTH_LONG).show();
		}
	}
	
	private void showDialog() {
		PassDialogFragment newFragment = PassDialogFragment.newInstance();
		newFragment.setTargetFragment(this, REQUEST_CODE);
		newFragment.show(getFragmentManager().beginTransaction(), "dialog");
	}
}